package org.apache.servicecomb.samples.practise.houserush.login.entity;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.apache.commons.lang.StringUtils;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.persistence.*;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;

@Data
@Entity
@Table(name = "users")
@SQLDelete(sql = "update users set deleted_at = now() where id = ?")
@Where(clause = "deleted_at is null")
@EntityListeners(AuditingEntityListener.class)
public class User {
    private final static String USER_SECRET = "OVDHqdO15lnvyCtzMkAM";
    private final static String HASH_TYPE = "HmacSHA256";
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    private String username;

    @JsonIgnore
    private String hashedPassword;
    @Temporal(TemporalType.TIMESTAMP)
    private Date deletedAt;
    @CreatedDate
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdAt;
    @LastModifiedDate
    @Temporal(TemporalType.TIMESTAMP)
    private Date updatedAt;
    @Transient
    private String password;
    @Transient
    private String oldPassword;
    @Transient
    private String token;

    public String makeHashedPassword(String password) {
        try {
            String data = username + password;
            SecretKey secretKey = new SecretKeySpec(USER_SECRET.getBytes(), HASH_TYPE);
            Mac mac = Mac.getInstance(HASH_TYPE);
            mac.init(secretKey);
            byte[] bytes = mac.doFinal(data.getBytes());
            return new String(Base64.getEncoder().encode(bytes));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public String generateToken() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MINUTE,240);
        Algorithm algorithm = Algorithm.HMAC256(USER_SECRET);
        token = JWT.create().withSubject(String.valueOf(id))
                .withExpiresAt(c.getTime())
                .sign(algorithm);
        return token;
    }

    private static Algorithm algorithm = null;

    private static JWTVerifier jwtVerifier = null;

    {
        algorithm = Algorithm.HMAC256(USER_SECRET);

        jwtVerifier = JWT.require(algorithm).build();
    }
    public static int verifyTokenGetUserId(String token) {
        DecodedJWT verify = jwtVerifier.verify(token);
        String sub = verify.getSubject();
        if(StringUtils.isNotBlank(sub)) {
            return Integer.parseInt(sub);
        } else {
            throw new RuntimeException("令牌验证失败");
        }
    }

    public static void main(String[] args) {
        User user = new User();
        user.setUsername("ww");
        String s = user.makeHashedPassword("1995924");
        System.out.println(s);
    }


}
